#include "dexiosfm.h"
#include "ui_dexiosfm.h"

#include <QDebug>
#include <QDesktopServices>
#include <QDir>
#include <QFileSystemModel>
#include <QIcon>
#include <QLabel>
#include <QListWidgetItem>
#include <QMovie>

#include "dexiosfmtab.h"

DexiosFM::DexiosFM(QWidget * parent)
	: QMainWindow(parent),
	  ui(new Ui::DexiosFM),
	  file_system(new QFileSystemModel(this)),
	  image_previewer(new QLabel(this))
	{
		setWindowState(Qt::WindowMaximized);

		ui->setupUi(this);
		ui->action_Add_to_Favorites->setIcon(QIcon::fromTheme("folder-favorites", QIcon(":/icons/folder-favorites.png")));
		ui->action_Delete->setIcon(QIcon::fromTheme("edit-delete", QIcon(":/icons/edit-delete.png")));
		ui->action_Go_Back->setIcon(QIcon::fromTheme("go-previous", QIcon(":/icons/go-previous.png")));
		ui->action_Go_Forward->setIcon(QIcon::fromTheme("go-next", QIcon(":/icons/go-next.png")));
		ui->action_Go_Home->setIcon(QIcon::fromTheme("user-home", QIcon(":/icons/user-home.png")));
		ui->action_Go_Up->setIcon(QIcon::fromTheme("go-up", QIcon(":/icons/go-up.png")));
		ui->action_Move_To_Trash->setIcon(QIcon::fromTheme("user-trash", QIcon(":/icons/user-trash.png")));
		ui->action_New_Directory->setIcon(QIcon::fromTheme("folder-new", QIcon(":/icons/folder-new.png")));
		ui->action_New_Tab->setIcon(QIcon::fromTheme("tab-new", QIcon(":/icons/tab-new.png")));
		ui->action_Refresh->setIcon(QIcon::fromTheme("view-refresh", QIcon(":/icons/view-refresh.png")));
		ui->action_Rename->setIcon(QIcon::fromTheme("edit-rename", QIcon(":/icons/edit-rename.png")));

		connect(ui->action_Go_Up, SIGNAL(triggered()),
				this, SLOT(goUp()));
		connect(ui->action_New_Tab, SIGNAL(triggered()),
				this, SLOT(addTab()));

		// Image previewer
		ui->imagePreviewArea->setBackgroundRole(QPalette::Dark);
		ui->imagePreviewArea->setWidget(image_previewer);

		ui->keepAspectRatioBtn->hide();
		ui->keepAspectRatioBtn->setChecked(false);

		image_previewer->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
		image_previewer->setScaledContents(true);

//		keepAspectRatio(true);

		connect(ui->exitPreviewBtn, SIGNAL(clicked()),
				this, SLOT(exitImagePreview()));
		connect(ui->keepAspectRatioBtn, SIGNAL(clicked(bool)),
				this, SLOT(keepAspectRatio(bool)));
		connect(ui->prevImageBtn, SIGNAL(clicked()),
				this, SLOT(previousImage()));
		connect(ui->nextImageBtn, SIGNAL(clicked()),
				this, SLOT(nextImage()));

		ui->menu_View->insertAction(0, ui->toolBar->toggleViewAction());
		ui->menu_View->insertAction(0, ui->toolBar_2->toggleViewAction());

		setupFavorites();

		file_system->setRootPath(QDir::rootPath());

		home_path = QDesktopServices::storageLocation(QDesktopServices::HomeLocation);
		addTab();

		connect(ui->favListView, SIGNAL(clicked(QModelIndex)),
				this, SLOT(openFav(QModelIndex)));

		connect(ui->tabWidget, SIGNAL(tabCloseRequested(int)),
				this, SLOT(closeTab(int)));
	}

DexiosFM::~DexiosFM()
	{
		delete ui;
	}

void DexiosFM::addTab()
	{
		if (QDir::home().exists())
			addTab(file_system->index(home_path));
	}

void DexiosFM::addTab(const QModelIndex & index)
	{
		DexiosFMTab * tab = new DexiosFMTab(file_system, this);

		connect(tab, SIGNAL(enableAddToFavorites(bool)),
				ui->action_Add_to_Favorites, SLOT(setEnabled(bool)));
		connect(tab, SIGNAL(enableDeleteAction(bool)),
				ui->action_Delete, SLOT(setEnabled(bool)));
		connect(tab, SIGNAL(enableGoBackAction(bool)),
				ui->action_Go_Back, SLOT(setEnabled(bool)));
		connect(tab, SIGNAL(enableGoForwardAction(bool)),
				ui->action_Go_Forward, SLOT(setEnabled(bool)));
		connect(tab, SIGNAL(enableGoUpAction(bool)),
				ui->action_Go_Up, SLOT(setEnabled(bool)));
		connect(tab, SIGNAL(enableDeleteAction(bool)),
				ui->action_Move_To_Trash, SLOT(setEnabled(bool)));
		connect(tab, SIGNAL(enableNewDirAction(bool)),
				ui->action_New_Directory, SLOT(setEnabled(bool)));
		connect(tab, SIGNAL(enableRenameAction(bool)),
				ui->action_Rename, SLOT(setEnabled(bool)));
		connect(tab, SIGNAL(previewImage()),
				this, SLOT(previewImage()));

		connect(tab, SIGNAL(currentPathChanged(DexiosFMTab*,QString)),
				this, SLOT(updateTabTitle(DexiosFMTab*,QString)));

		int i = ui->tabWidget->addTab(tab, index.data().toString());
		ui->tabWidget->setCurrentIndex(i);
		tab->openPath(index, false);
	}

void DexiosFM::changeEvent(QEvent * e)
	{
		QMainWindow::changeEvent(e);
		switch (e->type())
		{
			case QEvent::LanguageChange:
				ui->retranslateUi(this);
				break;
			default:
				break;
		}
	}

void DexiosFM::closeTab(int i)
	{
		if (ui->tabWidget->count() > 1)
		{
			ui->tabWidget->widget(i)->deleteLater();
			ui->tabWidget->removeTab(i);
		}
	}

void DexiosFM::exitImagePreview()
	{
		ui->stackedWidget->setCurrentIndex(0);
	}

void DexiosFM::goUp()
	{
		DexiosFMTab * tab = qobject_cast<DexiosFMTab*>(ui->tabWidget->currentWidget());
		if (tab)
			tab->goUp();
	}

void DexiosFM::keepAspectRatio(bool x)
	{
		ui->imagePreviewArea->setWidgetResizable(x);

		if (!x)
			image_previewer->adjustSize();
	}

void DexiosFM::nextImage()
	{
		if (DexiosFMTab * tab = qobject_cast<DexiosFMTab *>(ui->tabWidget->currentWidget()))
		{
			QModelIndex index = tab->nextImage();
			previewImage(index);
		}
	}

void DexiosFM::openFav(const QModelIndex & index)
	{
//		file_system->setFilter(QDir::AllEntries | QDir::Hidden);

		QString path = index.data(Qt::UserRole).toString();
		QModelIndex i = file_system->index(path);

		DexiosFMTab * tab = qobject_cast<DexiosFMTab*>(ui->tabWidget->currentWidget());
		if (tab)
			tab->openPath(i, true);

//		file_system->setFilter(QDir::AllEntries);
	}

void DexiosFM::previewImage()
	{
		if (DexiosFMTab * tab = qobject_cast<DexiosFMTab *>(ui->tabWidget->currentWidget()))
		{
			previewImage(tab->currentIndex());
		}
	}

void DexiosFM::previewImage(const QModelIndex & index)
	{
//		if (DexiosFMTab * tab = qobject_cast<DexiosFMTab *>(ui->tabWidget->currentWidget()))
//		{
			QString file_path = file_system->filePath(index);

			if (file_path.contains(QRegExp("\\.gif$")))
			{
				static QMovie * mov = new QMovie(this);
				mov->stop();
				image_previewer->setMovie(mov);
				mov->setFileName(file_path);
				mov->start();
			}

			else
			{
				QPixmap pix = QPixmap::fromImage(QImage(file_path));
				image_previewer->setPixmap(pix);
			}

			keepAspectRatio(ui->keepAspectRatioBtn->isChecked());
			ui->stackedWidget->setCurrentIndex(1);
//		}
	}

void DexiosFM::previousImage()
	{
		if (DexiosFMTab * tab = qobject_cast<DexiosFMTab *>(ui->tabWidget->currentWidget()))
		{
			QModelIndex index = tab->previousImage();
			previewImage(index);
		}
	}

void DexiosFM::setupFavorites()
	{
		QStringList loc;
		loc << QDesktopServices::storageLocation(QDesktopServices::HomeLocation)
#ifdef Q_WS_X11
			<< QDesktopServices::storageLocation(QDesktopServices::HomeLocation) + "/.local/share/Trash/files"
			<< "/"
#else
			<< ""
			<< "My Computer"
#endif
			<< QDesktopServices::storageLocation(QDesktopServices::DesktopLocation)
			<< QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation)
			<< QDesktopServices::storageLocation(QDesktopServices::MoviesLocation)
			<< QDesktopServices::storageLocation(QDesktopServices::PicturesLocation)
			<< QDesktopServices::storageLocation(QDesktopServices::MusicLocation);

#ifdef Q_WS_WIN
		foreach (QFileInfo info, QDir::drives())
			loc << info.absoluteFilePath();
#endif

		foreach (QString path, loc)
		{
			QDir dir(path);
			QIcon icon;
			QString name = path.split(QDir::toNativeSeparators("/")).last();

			int i = loc.indexOf(QRegExp(path));

			// Home
			if (i == 0)
			{
				icon = QIcon::fromTheme("user-home", QIcon(":/icons/user-home.png"));
				name = "Home";
			}

			// Trash
			else if (i == 1)
			{
#ifdef Q_WS_X11
				continue; // Trash requires a dirty hack to implement
				icon = QIcon::fromTheme("user-trash", QIcon(":/icons/user-trash.png"));
				name = "Trash";
#endif
			}

			// My Computer / Root
			else if (i == 2)
			{
#ifndef Q_WS_WIN
				icon = QIcon::fromTheme("folder-red");
				name = "Root";
#endif
			}

			// Desktop
			else if (i == 3)
				icon = QIcon::fromTheme("user-desktop", QIcon(":/icons/user-desktop.png"));

			// Documents
			else if (i == 4)
				icon = QIcon::fromTheme("folder-documents", QIcon(":/icons/folder-documents.png"));

			// Videos
			else if (i == 5)
				icon = QIcon::fromTheme("folder-video", QIcon(":/icons/folder-video.png"));

			// Pictures
			else if (i == 6)
				icon = QIcon::fromTheme("folder-image", QIcon(":/icons/folder-image.png"));

			// Music
			else if (i == 7)
				icon = QIcon::fromTheme("folder-sound", QIcon(":/icons/folder-sound.png"));

			// Drives
			else
				icon = QIcon::fromTheme("drive-harddisk", QIcon(":/icons/drive-harddisk.png"));


			if (dir.exists())
			{
				QListWidgetItem * item = new QListWidgetItem(icon, name, ui->favListView);
				item->setData(Qt::UserRole, path);
			}
		}
	}

void DexiosFM::updateTabTitle(DexiosFMTab * tab, const QString & title)
	{
		int i = ui->tabWidget->indexOf(tab);
		ui->tabWidget->setTabText(i, title);
	}
